package chapter4_对象组合.线程安全性委托;

import annotation.GuardedBy;
import annotation.NotThreadSafe;
import annotation.ThreadSafe;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * 监视器模式：内置锁(同步方法)
 *
 * 分析：Map<String, MutablePoint> locations和MutablePoint对象未曾发布
 * 结论：虽然MutablePoint不是线程安全的，但是MonitorVehicleTracker是线程安全的
 * 备注：大量的拷贝效率特别低
 */
@ThreadSafe
public class MonitorVehicleTracker {
    @GuardedBy("this")
    private final Map<String, MutablePoint> locations;

    public MonitorVehicleTracker(Map<String, MutablePoint> locations) {
        // 深度拷贝
        this.locations = deepCopy(locations);
    }

    // 同步方法
    public synchronized Map<String, MutablePoint> getLocations() {
        return deepCopy(locations);
    }

    // 同步方法
    public synchronized MutablePoint getLocation(String id) {
        MutablePoint loc = locations.get(id);
        // 拷贝一个对象返回
        return loc == null ? null : new MutablePoint(loc);
    }

    // 同步方法 间接访问MutablePoint
    public synchronized void setLocation(String id, int x, int y) {
        MutablePoint loc = locations.get(id);
        if (loc == null) {
            throw new IllegalArgumentException("No such ID: "+ id);
        }
        loc.x = x;
        loc.y = y;
    }



    private static Map<String, MutablePoint> deepCopy(Map<String, MutablePoint> m) {
        Map<String, MutablePoint> result = new HashMap<>();
        for (String id : m.keySet()) {
            result.put(id, new MutablePoint(m.get(id)));
        }
        return Collections.unmodifiableMap(result);
    }

}

@NotThreadSafe
class MutablePoint {
    public int x, y;
    public MutablePoint() {
        x = 0; y =0;
    }

    public MutablePoint(MutablePoint p) {
        this.x = p.x;
        this.y = p.y;
    }
}


